package com.easybbs.service.impl;

import java.util.Date;
import java.util.List;

import javax.annotation.Resource;
import javax.mail.MessagingException;
import javax.mail.internet.MimeMessage;

import com.easybbs.config.WebConfig;
import com.easybbs.entity.dto.SysSetting4EmailDto;
import com.easybbs.entity.enums.*;
import com.easybbs.entity.po.SysSetting;
import com.easybbs.exception.BusinessException;
import com.easybbs.service.SysSettingService;
import com.easybbs.utils.JsonUtils;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.mail.javamail.JavaMailSender;
import org.springframework.mail.javamail.MimeMessageHelper;
import org.springframework.stereotype.Service;

import com.easybbs.entity.query.EmailCodeQuery;
import com.easybbs.entity.po.EmailCode;
import com.easybbs.entity.vo.PaginationResultVO;
import com.easybbs.entity.query.SimplePage;
import com.easybbs.mappers.EmailCodeMapper;
import com.easybbs.service.EmailCodeService;
import com.easybbs.utils.StringTools;
import org.springframework.transaction.annotation.Transactional;
import org.springframework.util.ObjectUtils;


/**
 * 邮箱验证码 业务接口实现
 */
@Service("emailCodeService")
public class EmailCodeServiceImpl implements EmailCodeService {

	private static final Logger log = LoggerFactory.getLogger(EmailCodeServiceImpl.class);
	@Resource
	private EmailCodeMapper<EmailCode, EmailCodeQuery> emailCodeMapper;

	@Resource
	private JavaMailSender javaMailSender;

	@Resource
	private WebConfig webConfig;

	@Resource
	private SysSettingService sysSettingService;

	/**
	 * 根据条件查询列表
	 */
	@Override
	public List<EmailCode> findListByParam(EmailCodeQuery param) {
		return this.emailCodeMapper.selectList(param);
	}

	/**
	 * 根据条件查询列表
	 */
	@Override
	public Integer findCountByParam(EmailCodeQuery param) {
		return this.emailCodeMapper.selectCount(param);
	}

	/**
	 * 分页查询方法
	 */
	@Override
	public PaginationResultVO<EmailCode> findListByPage(EmailCodeQuery param) {
		int count = this.findCountByParam(param);
		int pageSize = param.getPageSize() == null ? PageSize.SIZE15.getSize() : param.getPageSize();

		SimplePage page = new SimplePage(param.getPageNo(), count, pageSize);
		param.setSimplePage(page);
		List<EmailCode> list = this.findListByParam(param);
		PaginationResultVO<EmailCode> result = new PaginationResultVO(count, page.getPageSize(), page.getPageNo(), page.getPageTotal(), list);
		return result;
	}

	/**
	 * 新增
	 */
	@Override
	public Integer add(EmailCode bean) {
		return this.emailCodeMapper.insert(bean);
	}

	/**
	 * 批量新增
	 */
	@Override
	public Integer addBatch(List<EmailCode> listBean) {
		if (listBean == null || listBean.isEmpty()) {
			return 0;
		}
		return this.emailCodeMapper.insertBatch(listBean);
	}

	/**
	 * 批量新增或者修改
	 */
	@Override
	public Integer addOrUpdateBatch(List<EmailCode> listBean) {
		if (listBean == null || listBean.isEmpty()) {
			return 0;
		}
		return this.emailCodeMapper.insertOrUpdateBatch(listBean);
	}

	/**
	 * 多条件更新
	 */
	@Override
	public Integer updateByParam(EmailCode bean, EmailCodeQuery param) {
		StringTools.checkParam(param);
		return this.emailCodeMapper.updateByParam(bean, param);
	}

	/**
	 * 多条件删除
	 */
	@Override
	public Integer deleteByParam(EmailCodeQuery param) {
		StringTools.checkParam(param);
		return this.emailCodeMapper.deleteByParam(param);
	}

	/**
	 * 根据EmailAndCode获取对象
	 */
	@Override
	public EmailCode getEmailCodeByEmailAndCode(String email, String code) {
		return this.emailCodeMapper.selectByEmailAndCode(email, code);
	}

	/**
	 * 根据EmailAndCode修改
	 */
	@Override
	public Integer updateEmailCodeByEmailAndCode(EmailCode bean, String email, String code) {
		return this.emailCodeMapper.updateByEmailAndCode(bean, email, code);
	}

	/**
	 * 根据EmailAndCode删除
	 */
	@Override
	public Integer deleteEmailCodeByEmailAndCode(String email, String code) {
		return this.emailCodeMapper.deleteByEmailAndCode(email, code);
	}

	@Override
	@Transactional(rollbackFor = Exception.class)
	public void sendEmailCode(String email, String sendEmailCode, Integer emailCodeType) {
		EmailCodeTypeEnum emailCodeTypeEnum = EmailCodeTypeEnum.getEnumByCode(emailCodeType);
		if (ObjectUtils.isEmpty(emailCodeTypeEnum)) {
			throw new BusinessException(ResponseCodeEnum.CODE_600);
		}
		// 先将这个邮箱未使用的验证码更新成已使用
		EmailCode emailCode = new EmailCode();
		emailCode.setStatus(EmailCodeStatusEnum.USED.getCode());
		EmailCodeQuery emailCodeQuery = new EmailCodeQuery();
		emailCodeQuery.setEmail(email);
		emailCodeQuery.setStatus(EmailCodeStatusEnum.UN_USED.getCode());
		emailCodeMapper.updateByParam(emailCode, emailCodeQuery);

		// 发送验证码，并且保存到数据库
		// TODO 消息队列优化，异步解耦
		this.sendEmail(email, sendEmailCode, emailCodeTypeEnum);

		// 保存验证码到数据库
		EmailCode emailCodeSave = new EmailCode();
		emailCodeSave.setEmail(email);
		emailCodeSave.setCode(sendEmailCode);
		emailCodeSave.setCreateTime(new Date());
		emailCodeSave.setStatus(EmailCodeStatusEnum.UN_USED.getCode());
		emailCodeMapper.insert(emailCodeSave);
	}

	public void sendEmail(String email, String code, EmailCodeTypeEnum emailCodeTypeEnum) {
		try {
			MimeMessage mimeMessage = javaMailSender.createMimeMessage();
			MimeMessageHelper messageHelper = new MimeMessageHelper(mimeMessage, true);
			messageHelper.setFrom(webConfig.getSendUserName());
			messageHelper.setTo(email);
			SysSetting sysSetting = sysSettingService.getSysSettingByCode(SysSettingCodeEnum.EMAIL.getCode());
			SysSetting4EmailDto sysSetting4EmailDto = JsonUtils.convertJson2Obj(sysSetting.getJsonContent(), SysSetting4EmailDto.class);
			if (emailCodeTypeEnum.equals(EmailCodeTypeEnum.REGISTER)) {
				messageHelper.setSubject(String.format(sysSetting4EmailDto.getEmailTitle(), "注册-"));
			} else {
				messageHelper.setSubject(String.format(sysSetting4EmailDto.getEmailTitle(), "找回密码-"));
			}
			messageHelper.setText(String.format(sysSetting4EmailDto.getEmailContent(), code));
			messageHelper.setSentDate(new Date());
			javaMailSender.send(mimeMessage);
		} catch (Exception e) {
			log.error("发送邮件失败", e);
			throw new BusinessException("发送邮件失败");
		}
	}
}